#include "led.h"


#define USER_LED_TASK_PRIO 2			/* 定义任务优先级 */
#define USER_LED_TASK_STACK_SIZE 120	/* 定义任务堆栈大小 */
TaskHandle_t user_led_handle;			/* 定义任务句柄 */
void led_task(void* pvParameters); /* 任务函数 */

static void init(struct Led* led);
static void toggle(struct Led* led);
static void on(struct Led* led);
static void off(struct Led* led);
static void led_create_task(void);


static void led_create_task(void)
{
  xTaskCreate(
        (TaskFunction_t)led_task,
        (const char*)"led_task",
        (uint16_t)USER_LED_TASK_STACK_SIZE,
        (void*)NULL,
        (UBaseType_t)USER_LED_TASK_PRIO,
        (TaskHandle_t*)user_led_handle
  );
}

// 创建一个 LED 对象
struct Led led1 = {
    .gpiox = GPIOA,
    .pins = GPIO_PINS_0,
    .crm_periph_clock = CRM_GPIOA_PERIPH_CLOCK,
    .pull = GPIO_PULL_NONE,
    .init = init,
    .off = off,
    .on = on,
    .toggle = toggle,
	.create_task = led_create_task
};


static void init(struct Led* led)
{
     /* 定义 GPIO 初始化结构体 */
    gpio_init_type gpio_init_struct;

    /* 使能 GPIOA 外设时钟 */
    crm_periph_clock_enable(led->crm_periph_clock, TRUE);

    /* 设置默认参数 */
    gpio_default_para_init(&gpio_init_struct);

    /* 配置 GPIO 参数 */
    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; /* 较大电流推动/吸入能力 */
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; /* 推挽输出 */
    gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
    gpio_init_struct.gpio_pins = led->pins;
    gpio_init_struct.gpio_pull = led->pull;
    gpio_init(led->gpiox, &gpio_init_struct);
}

/// @brief led FreeRTOS 任务函数
/// @param pvParameters 
void led_task(void* pvParameters)
{
    led1.init(&led1);
    uint32_t num = 0;
    uint32_t ul_notify_value;
    while (1)
    {
        ul_notify_value = ulTaskNotifyTake(pdTRUE, 0);
        if (ul_notify_value>0)
        {
            led1.toggle(&led1);
        }
    }
}

void toggle(struct Led* led)
{
    led->gpiox->odt ^= led->pins;
}

void on(struct Led* led)
{
    gpio_bits_write(led->gpiox, led->pins, TRUE);
}

void off(struct Led* led)
{
    gpio_bits_write(led->gpiox, led->pins, FALSE);
}